package log

//当程序因为未知失原因死掉
import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"golang.org/x/sys/unix"
)

var (
	stack *os.File
	once  sync.Once
)

//TraceStacks当程序发生未知的错误时，打印出go的所有协程信息
func TraceStacks(opts ...Option) error {
	var err error
	once.Do(func() {
		opt := Options{
			stackAppendLog: true,
			stackFileName:  os.Args[0],
			stackDirectory: "./",
		}
		for _, o := range opts {
			o(&opt)
		}
		fileMod := os.O_CREATE | os.O_RDWR
		//append模式
		if opt.stackAppendLog == true {
			fileMod |= os.O_APPEND
			opt.stackFileName = fmt.Sprintf("%s-stack.log", opt.stackFileName)
		} else {
			opt.stackFileName = getFormatFileName(opt.stackFileName)
		}
		tmpF, er := os.OpenFile(filepath.Join(opt.stackDirectory, opt.stackFileName), fileMod, 0755)
		if er != nil {
			err = er
			return
		}
		stack = tmpF
		err := unix.Dup2(int(stack.Fd()), 2)
		if err != nil {
			err = er
			return
		}
		return
	})
	return err
}

func ClsoeStack() error {
	return stack.Close()
}
